/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package estructurassa.estrategias;

import estructurassa.entidades.Demanda;
import estructurassa.entidades.Material;
import estructurassa.entidades.Pieza;
import java.util.List;

/**
 *
 * @author diego
 */
public class EstrategiaStock {

    public Float calcularLoteOptimo(Pieza pieza) {
        Material material = (Material) pieza;
        Demanda ultimaDemanda = ultimaDemanda(material.getHistoricoDemanda());

        Double loteOptimo = Math.sqrt((2 * material.getCostoPedido() * ultimaDemanda.getCantidad()) / material.getCostoAlmacenamiento());

        return Float.valueOf(loteOptimo.toString());
    }

    protected Demanda ultimaDemanda(List<Demanda> demandas) {
        Demanda ultima;
        if (!demandas.isEmpty()) {
            ultima = demandas.get(0);
            for (Demanda demanda : demandas) {
                ultima = getMayorDemanda(ultima, demanda);
            }
        } else {
            ultima = new Demanda();
            ultima.setCantidad(0f);
        }

        return ultima;
    }

    private Demanda getMayorDemanda(Demanda demanda1, Demanda demanda2) {

        if (demanda1.getAnio() > demanda2.getAnio()) {
            return demanda1;
        } else if (demanda1.getAnio() < demanda2.getAnio()) {
            return demanda2;
        }

        if (demanda1.getMes() > demanda2.getMes()) {
            return demanda1;
        } else if (demanda1.getMes() < demanda2.getMes()) {
            return demanda2;
        }
        return demanda1;
    }

    public Float calcularCantidadPedidosOptima(Pieza pieza) {
        Demanda demanda = ultimaDemanda(pieza.getHistoricoDemanda());
        Float cantidadOptima;
        cantidadOptima = demanda.getCantidad() / calcularLoteOptimo(pieza);
        return cantidadOptima;
    }

    public Float calcularTiempoOptimoPedido(Pieza pieza) {
        Float tiempoOptimo = 1 / calcularCantidadPedidosOptima(pieza);
        return tiempoOptimo;
    }

    public Float calcularCostoGestionInventario(Pieza pieza) {
        Material material = (Material) pieza;
        Float costoCompra = material.getMenorPrecio().getMonto() * calcularLoteOptimo(pieza);
        Float costoPedido = material.getCostoPedido();
        Float costoAlmacenamiento = material.getCostoAlmacenamiento();

        Float costoGestionInventario = costoAlmacenamiento + costoCompra + costoPedido;

        return costoGestionInventario;

    }

    public Float calcularStockSeguridad(Pieza pieza) {
        Double tiempoOptimo = Double.valueOf(calcularTiempoOptimoPedido(pieza));
        Double demanda = Double.valueOf(ultimaDemanda(pieza.getHistoricoDemanda()).getCantidad());
        Double precio = Double.valueOf(((Material) pieza).getMenorPrecio().getMonto());
        Double stockSeguridad = Math.sqrt(demanda * tiempoOptimo * precio);
        return Float.valueOf(stockSeguridad.toString());

    }

    public Float calcularPuntoPedido(Pieza pieza) {
        Float demandaEstimada = demandaEstimadaEnPlazoAporvicionamiento(pieza);
        Float stockSeguridad = calcularStockSeguridad(pieza);
        Float puntoPed = demandaEstimada + stockSeguridad;
        return puntoPed;

    }

    private Float demandaEstimadaEnPlazoAporvicionamiento(Pieza pieza) {
        Float demandaDiaria = ultimaDemanda(pieza.getHistoricoDemanda()).getCantidad() / 30;
        Float plazoAprovicionamiento = ((Material) pieza).getMenorPrecio().getProveedor().getTiempoDemora();
        Float demandaEstimadaEnPlazoAprov = demandaDiaria * plazoAprovicionamiento;
        return demandaEstimadaEnPlazoAprov;
    }
}
